package com.ygqh.baby.service.task.impl;

import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.mp.message.TemplateMessage;
import com.foxinmy.weixin4j.util.StringUtil;
import com.wdt.api.response.StockOutOrderQueryTradeResponse;
import com.wdt.api.response.StockQueryResponse;
import com.wdt.api.response.TradeQueryResponse;
import com.wdt.api.response.support.Stock;
import com.wdt.api.response.support.StockOutOrderTradeDTO;
import com.wdt.api.response.support.TradeDetail;
import com.wdt.api.response.support.TradesDTO;
import com.wdt.api.util.DateUtils;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.model.MsgModel;
import com.ygqh.baby.model.kdniao.request.ContactInfo;
import com.ygqh.baby.model.wdt.qyb.*;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.ngmm.util.NgmmConfigure;
import com.ygqh.baby.service.task.YgWdtTaskService;
import com.ygqh.baby.service.wdtqyb.api.WdtQybApi;
import com.ygqh.baby.service.wdtqyb.builder.WdtOrderBuiler;
import com.ygqh.baby.service.wdtqyb.exception.WdtException;
import com.ygqh.baby.service.wechat.message.YgTemplateMessage;
import com.ygqh.baby.utils.*;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author (guohao)
 * @version V1.0
 * @ClassName: YgWdtTaskServiceImpl
 * @date 2018年7月12日 下午4:36:27
 */
@Service
public class YgWdtTaskServiceImpl implements YgWdtTaskService {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private YgTaskTimeService ygTaskTimeService;
    @Autowired
    private WdtQybApi wdtQybApi;
    @Autowired
    private YgReturnOrderService ygReturnOrderService;
    @Autowired
    private YgReturnOrderLogService ygReturnOrderLogService;
    @Autowired
    private YgLogisticsService ygLogisticsService;
    @Autowired
    private WxMpMessageService wxMpMessageService;
    @Autowired
    private YgOrderService ygOrderService;
    @Autowired
    private WxMpAuthorityService wxMpAuthorityService;
    @Autowired
    private YgOrderLogService ygOrderLogService;
    @Autowired
    private YgUserService ygUserService;
    @Autowired
    private SmsService smsService;
    @Autowired
    private YgProductService ygProductService;
    @Autowired
    private YgReturnOrderDetailService ygReturnOrderDetailService;
    @Autowired
    private YgCouponDetailService ygCouponDetailService;
    @Autowired
    private WdtQybOrderService wdtQybOrderService;
    @Autowired
    private WdtQybStockInService wdtQybStockInService;
    @Autowired
    private AdminPurchaseService adminPurchaseService;
    @Autowired
    private WdtQybStockOutService wdtQybStockOutService;
    @Autowired
    private YgStockService ygStockService;
    @Autowired
    private YgOrderDetailService ygOrderDetailService;
    @Autowired
    private WdtQybLogisticsService wdtQybLogisticsService;
    @Autowired
    private ThreadPool threadPool;
    @Autowired
    private YgNgmmService ygNgmmService;
    @Autowired
    private ScheduleJobService scheduleJobService;
    @Autowired
    private AppMessageService appMessageService;
    @Autowired
    private YgCardCouponDetailService ygCardCouponDetailService;
    @Autowired
    private YgSupplierService ygSupplierService;
    @Autowired
    private KidsOrderLogisticsService kidsOrderLogisticsService;
    @Autowired
    private YgWholesalerDeliveryOrderDetailService ygWholesalerDeliveryOrderDetailService;
    @Autowired
    private WdtQybTradeService wdtQybTradeService;
    @Autowired
    private WxSmallMessageService wxSmallMessageService;

    @Value("${promotion.link}")
    protected String promotionLink;
    @Value("${warehouse_no}")
    protected String warehouseNo;
    @Value("${production.mode}")
    protected Boolean productionMode;

    private final static ExecutorService executorService = Executors.newFixedThreadPool(3);

    @Override
    public void syncLogistics(int timeInterval) {
        WdtSyncLogisticsResult result = null;
        try {
            result = wdtQybApi.syncLogistics(100, 1);
        } catch (WdtException e) {
            logger.error("同步物流信息失败;" + e.getMessage());
            e.printStackTrace();
        }
        if (result != null) {

            List<WdtSyncLogistics> trades = result.getTrades();

            List<YgOrderDetail> sendDetailList = new ArrayList<YgOrderDetail>();

            List<YgOrder> orderList = new ArrayList<YgOrder>();

            List<YgOrderLog> orderLogs = new ArrayList<YgOrderLog>();
            List<YgLogistics> logisticsList = new ArrayList<YgLogistics>();
            List<WdtSyncLogisticsBack> syncBack = new ArrayList<>();
            List<WdtSyncLogistics> loadList = new ArrayList<WdtSyncLogistics>();

            MsgModel msg = new MsgModel();

            for (WdtSyncLogistics trade : trades) {
                // 是否为M站订单

                if (!isMOrder(trade.getShopNo())) {
                    continue;
                }
                if (StringUtil.isEmpty(trade.getTid())) {
                    logger.warn(trade.getTradeId() + ":该单据是手动同步单据，且没有维护原始单号");
                    continue;
                }
                String orderCode = WdtOrderBuiler.getOrderIdFromTid(trade.getTid());
                boolean isNum = orderCode.matches("[0-9]+");

                // 物流信息
                YgLogistics logistics = new YgLogistics(orderCode, trade.getLogisticsName(), "", trade.getLogisticsNo(), trade.getConsignTime(), new Date());

                String oidsStr = trade.getOids();

                try {
                    List<YgLogistics> list = ygLogisticsService.findByExpressCode(orderCode, logistics.getExpressCode());
                    if (CollectionUtils.isEmpty(list)) {
                        if (isNum) {
                            // 普通订单
                            syncSendOrder(trade.getTid(), oidsStr, trade, orderList, sendDetailList, orderLogs, logisticsList, logistics, msg);
                        } else {
                            // 换货单
                            syncSendChangeOrder(trade, oidsStr, orderCode, logistics, msg);
                        }
                    }
                    WdtSyncLogisticsBack back = new WdtSyncLogisticsBack(trade.getRecId(), 0, "");
                    syncBack.add(back);
                    loadList.add(trade);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                    e.printStackTrace();
                }

            }
            if (syncBack.size() > 0) {
                ygOrderService.updateStatus4SendByTask(orderList, sendDetailList);
                ygLogisticsService.addLogisticsBatch(logisticsList);
                kdNiaoSubscribe(logisticsList);
                addQuartzJob(orderList);
                ygOrderLogService.addOrderLogBatch(orderLogs);
                sendOrderSendMsg(msg);
                try {
                    wdtQybApi.syncLogisticsBack(syncBack);
                } catch (WdtException e) {
                    e.printStackTrace();
                    logger.error("【syncLogistics】:同步回调失败，" + e.getMessage() + ";" + syncBack.toString());
                }
                this.loadLogistics(loadList);

            }
            ygTaskTimeService.saveOrUpdate(TaskMethod.SyncLogistics.name(), new Date(), "正常");

        }
    }


    private void kdNiaoSubscribe(List<YgLogistics> logisticsList) {
        if (CollectionUtils.isEmpty(logisticsList)) {
            return;
        }
        executorService.execute(() -> logisticsList.forEach(l -> {

            ContactInfo receiver = new ContactInfo(l.getReceiver(), l.getPhone(), l.getProvinceName(), l.getCityName(), l.getAreaName(),
                    l.getAddress());
            KdNiaoUtil.orderTracesSub(l.getLogisticsCode(), l.getUserId(), l.getOrderId(), l.getExpressCode(), receiver, productionMode);
        }));

    }

    private Boolean isMOrder(String shopNo) {
        if (shopNo.equals("002") || shopNo.equals("035") || shopNo.equals("ygqh2-test")) {
            return true;
        }
        return false;
    }

    private void addQuartzJob(List<YgOrder> orderList) {
        for (YgOrder ygOrder : orderList) {
            executorService.execute(() -> scheduleJobService.addBalanceJob(ygOrder.getOrderId(), ygOrder.getSendTime(), "task"));

        }
    }

    private void sendOrderSendMsg(MsgModel msgModel) {
        List<TemplateMessage> wxMsgList = msgModel.getWxMsgList();
        List<YgMobile> mobileMsgList = msgModel.getMobileMsgList();
        List<Map<String, String>> appMsgList = msgModel.getAppMsgList();

        if (CollectionUtils.isNotEmpty(wxMsgList)) {

            for (TemplateMessage msg : wxMsgList) {
                if (msg == null) {
                    continue;
                }
                if (msg instanceof YgTemplateMessage) {
                    wxSmallMessageService.sendTmplMsg((YgTemplateMessage) msg);
                } else {
                    wxMpMessageService.sendTemplateMessage(msg);
                }
            }
        }
        if (CollectionUtils.isNotEmpty(mobileMsgList)) {

            for (YgMobile ygMobile : mobileMsgList) {
                if (ygMobile == null) {
                    continue;
                }
                try {
                    smsService.sendSms(ygMobile.getMobile().toString(), ygMobile.getContent());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        if (CollectionUtils.isNotEmpty(appMsgList)) {
            for (Map<String, String> map : appMsgList) {
                String orderId = map.get("orderId");
                String userId = map.get("userId");
                String orderType = map.get("orderType");
                appMessageService.sendOrderDeliveryNotice(orderId, userId, orderType, null);
            }
        }
    }

    private TemplateMessage getOrderSendMsg(String openId, String url, String orderCode, String productName, WdtSyncLogistics trade) {
        if (StringUtil.isBlank(productName)) {
            return null;
        }

        String title = "亲，您购买的壹果商品已经发货啦！收到商品后请给予评价哦！";

        String tempId = wxMpMessageService.getWxMsgTempId(WxMessageType.WaitingSign);
        TemplateMessage tplMessage = new TemplateMessage(openId, tempId, title, url);
        tplMessage.pushHead("#323232", title);
        tplMessage.pushItem("delivername", "#323232", trade.getLogisticsName());
        tplMessage.pushItem("ordername", "#323232", trade.getLogisticsNo());
        tplMessage.pushItem("remark", "#323232", "订单编号：" + orderCode + "\n" + "商品名称：" + productName.substring(0, (productName.length() - 1)));
        return tplMessage;
    }

    private TemplateMessage getChangeOrderSendMsg(String openId, String orderCode, String productNames, WdtSyncLogistics trade) {
        if (StringUtil.isBlank(productNames)) {
            return null;
        }
        String tempId = wxMpMessageService.getWxMsgTempId(WxMessageType.WaitingSign);
        String url = promotionLink + "/return/viewProgress.html";
        String title = "亲，您的换货商品已经发出啦，感谢您对壹果的支持。";
        TemplateMessage tplMessage = new TemplateMessage(openId, tempId, title, url);

        tplMessage.pushHead("#323232", title);
        tplMessage.pushItem("delivername", "#323232", trade.getLogisticsName());
        tplMessage.pushItem("ordername", "#323232", trade.getLogisticsNo());
        tplMessage.pushItem("remark", "#323232", "商品详细：" + productNames.substring(0, (productNames.length() - 1)) + "\n" + "订单编号：" + orderCode);
        return tplMessage;
    }

    private void syncSendOrder(String tid, String oidsStr, WdtSyncLogistics trade, List<YgOrder> orderList, List<YgOrderDetail> sendDetailList,
                               List<YgOrderLog> orderLogs, List<YgLogistics> logisticsList, YgLogistics logistics, MsgModel msg) {
        StringBuilder buf = new StringBuilder();
        int sendCount = 0;
        Boolean handle = true;
        List<YgOrderDetail> detailList;
        String orderCode = WdtOrderBuiler.getOrderIdFromTid(tid);
        logger.info("syncSendOrder.tid=【{}】,orderCode=【{}】,oidsStr=【{}】", tid, orderCode, tid);
        if (tid.startsWith("S")) {
            detailList = ygOrderDetailService.findByOutCode(tid);
        } else {
            detailList = ygOrderDetailService.findByOrderId(Long.parseLong(orderCode));
        }

        if (CollectionUtils.isEmpty(detailList)) {
            return;
        }
        YgOrder ygOrder = ygOrderService.findByOrderId(detailList.get(0).getOrderId());
        if (ygOrder == null) {
            return;
        }
        ygOrder.setOrderDetail(detailList);
        YgUser user = ygUserService.findById(ygOrder.getUserId());

        if (StringUtil.isBlank(trade.getOids())) {
            ygOrder.setExpressCode("false");
            for (YgOrderDetail detail : detailList) {
                if (ygSupplierService.isSyncWDT(detail.getSupplierId())) {

                    detail.setSendMark(logistics.getExpressCode());
                    detail.setDetailStatus(OrderDetailStatus.WaitingSign);
                    sendDetailList.add(detail);
                    buf.append(detail.getProductName()).append(",");
                    sendCount++;
                }
            }

        } else {
            ygOrder.setExpressCode("true");
            String[] oids = oidsStr.split(",");
            for (int i = 0; i < oids.length; i++) {
                String[] oid = oids[i].split("-");
                /**
                 * oid = orderId +"-"+detailId
                 */
                String orderId = oid[0];
                long detailId = Long.parseLong(oid[1]);
                if (orderId.equals(orderCode)) {
                    for (YgOrderDetail detail : ygOrder.getOrderDetail()) {
                        if (detailId == detail.getId()) {
                            detail.setDetailStatus(OrderDetailStatus.WaitingSign);
                            detail.setSendMark(logistics.getExpressCode());
                            sendDetailList.add(detail);
                            buf.append(detail.getProductName()).append(",");
                            sendCount++;
                        }
                    }
                }
            }
        }
        if (ygOrder.getOrderStatus().equals(OrderStatus.WaitingSend)) {
            // IsPartSync= 1，则表示该单据为拆单单据
            // 第一次发货
            // 用于存放改成发货商品种类
            ygOrder.setLogisticsCode(sendCount + "");
            ygOrder.setOrderStatus(OrderStatus.WaitingSign);

        } else if (ygOrder.getOrderStatus().equals(OrderStatus.WaitingSign)) {
            // 第n次发货
            int amount = Integer.parseInt(ygOrder.getLogisticsCode() == null ? "0" : ygOrder.getLogisticsCode());
            ygOrder.setLogisticsCode((amount + sendCount) + "");

        }
        // 该订单在本地系统处于，完成状态不做任何处理
        else if (ygOrder.getOrderStatus().equals(OrderStatus.TradeSuccess)) {
            handle = false;
            ygOrderLogService.addOrderLog(ygOrder.getOrderId(), OrderStatus.TradeSuccess, "orderStatus4Send", "当前订单在本地处于完成状态。旺店通方面存在发货动作。wdtCode=" + orderCode);
        }

        if (handle) {

            String url = promotionLink + "/user/orderdetail.html?orderId=" + orderCode;
            ygOrder.setSendTime(trade.getConsignTime());
            orderList.add(ygOrder);

            TemplateMessage orderSendMsg;
            if (Constant.YIJIADIAN_PLATFORM_NO.equals(ygOrder.getPlatformNo())) {
                orderSendMsg = wxSmallMessageService.getOrderSendMsgByPlatform(ygOrder, trade.getLogisticsName(), trade.getLogisticsNo());
            } else {
                orderSendMsg = getOrderSendMsg(user.getOpenId(), url, orderCode, buf.toString(), trade);
            }

            if (orderSendMsg != null && YgStringUtils.isChinaPhoneLegal(user.getUserName())) {
                String mobileTitle = "亲，您购买的壹果商品已经发货啦！收到商品后请给予评价哦！商品持续上新中，希望您继续关注壹果！";
                YgMobile mobileMsg = new YgMobile(Long.parseLong(user.getUserName()), mobileTitle);
                msg.putMobileMsg(mobileMsg);
            }

            // app 消息
            /*Map<String, String> appMsg = new HashMap<>();
            appMsg.put("orderId", ygOrder.getOrderId().toString());
            appMsg.put("userId", user.getId().toString());
            appMsg.put("orderType", "order");
            msg.putAppMsg(appMsg);*/

            YgOrderLog log = new YgOrderLog(ygOrder.getOrderId(), ygOrder.getOrderStatus(), "定时任务，同步订单发货状态", "系统定时任务", new Date());
            orderLogs.add(log);

            msg.putWxMsg(orderSendMsg);

            logistics.setUserId(ygOrder.getUserId());
            logistics.setReceiver(ygOrder.getReceiver());
            logistics.setPhone(ygOrder.getTelPhone());
            logistics.setProvinceName(ygOrder.getProvinceName());
            logistics.setCityName(ygOrder.getCityName());
            logistics.setAreaName(ygOrder.getAreaName());
            logistics.setAddress(ygOrder.getAddress());
            logisticsList.add(logistics);
        }

        // 年糕妈妈订单快递信息同步
        if (ygOrder.getSupplierId().equals(NgmmConfigure.DEFAULT_SUPPLIER_ID)) {
            ygNgmmService.updateNgmmExpress(ygOrder.getOrderId().toString(), logistics.getLogisticsCode(), logistics.getExpressCode());
        }
    }

    private void syncSendChangeOrder(WdtSyncLogistics trade, String oidsStr, String orderCode, YgLogistics logistics, MsgModel msg) {

        List<YgReturnOrderDetail> detailList = new ArrayList<YgReturnOrderDetail>();
        List<YgOrderDetail> orderDetailList = new ArrayList<YgOrderDetail>();
        StringBuilder buf = new StringBuilder();
        int sendCount = 0;
        // 换货单
        YgReturnOrder changeOrder = ygReturnOrderService.findDetailByReCode(orderCode);
        if (changeOrder != null) {
            List<YgOrderDetail> orderDetails = ygOrderService.findDetails(changeOrder.getOrderId());
            YgUser user = ygUserService.findById(changeOrder.getUserId());
            // 没有拆单
            if (StringUtil.isBlank(oidsStr)) {
                YgOrder order = ygOrderService.findOrderDetailByOrderId(changeOrder.getOrderId());
                for (YgReturnOrderDetail rod : changeOrder.getReturnOrderDetails()) {
                    rod.setDetailStatus(OrderDetailStatus.WaitingSign);
                    rod.setSendMark(logistics.getExpressCode());
                    if (CollectionUtils.isNotEmpty(orderDetails)) {
                        for (YgOrderDetail detail : order.getOrderDetail()) {
                            if (detail.getId().equals(rod.getOdId())) {
                                detail.setSendMark(logistics.getExpressCode());
                                if (OrderDetailStatus.WaitingSend.equals(detail.getDetailStatus())) {
                                    detail.setDetailStatus(OrderDetailStatus.WaitingSign);
                                }
                                orderDetailList.add(detail);
                            }
                        }
                    }
                }
                detailList.addAll(changeOrder.getReturnOrderDetails());
            } else {
                String[] oids = oidsStr.split(",");
                for (int i = 0; i < oids.length; i++) {
                    String[] oid = oids[i].split("-");
                    if (oid.length == 1) {
                        // 手动添加的商品
                    } else {
                        String returnCode = oid[0];
                        long detailId = Long.parseLong(oid[1]);
                        if (returnCode.equals(orderCode)) {
                            if (oid.length == 2) {
                                for (YgReturnOrderDetail rod : changeOrder.getReturnOrderDetails()) {
                                    if (detailId == rod.getId().longValue()) {
                                        rod.setDetailStatus(OrderDetailStatus.WaitingSign);
                                        rod.setSendMark(logistics.getExpressCode());
                                        detailList.add(rod);
                                        buf.append(rod.getProductName() + ",");
                                        sendCount++;
                                        if (CollectionUtils.isNotEmpty(orderDetails)) {
                                            for (YgOrderDetail detail : orderDetails) {
                                                if (detail.getId().equals(rod.getOdId())) {
                                                    detail.setSendMark(logistics.getExpressCode());
                                                    orderDetailList.add(detail);
                                                }
                                            }
                                        }
                                    }
                                }
                            } else if (CollectionUtils.isNotEmpty(orderDetails)) {
                                // 这里处理的是 退货换货件数 < 购买件数
                                for (YgOrderDetail detail : orderDetails) {
                                    if (detail.getId().longValue() == detailId) {
                                        detail.setSendMark(logistics.getExpressCode());
                                        orderDetailList.add(detail);
                                    }
                                }

                            }
                        }
                    }
                }
            }
            Boolean isFirst = false;
            if (changeOrder.getReturnStatus().equals(ReturnStatus.WaitingSend)) {
                isFirst = true;
            }

            ygLogisticsService.save(logistics);
            // 设置此次发货时间
            changeOrder.setSendTime(trade.getConsignTime());
            if (changeOrder.getReturnStatus().equals(ReturnStatus.WaitingSend)) {
                changeOrder.setReturnStatus(ReturnStatus.WaitingSign);
            }
            int sendAmount = changeOrder.getSendCount().intValue();
            sendAmount = sendCount + sendAmount;
            changeOrder.setSendCount((long) sendAmount);
            changeOrder.setUpdateBy("syncLogistics");
            changeOrder.setUpdateTime(new Date());

            ygReturnOrderService.update(changeOrder);
            ygReturnOrderDetailService.updateSendBatch(detailList);
            ygOrderDetailService.updateDetailSendBatch(orderDetailList);

            if (isFirst) {
                ygReturnOrderLogService.addReturnOrderLog(orderCode, "发货后7天完成，感谢您对我们工作的支持。", ReturnStatus.WaitingSign, "syncLogistics", null);
            }
            TemplateMessage wxmsg = getChangeOrderSendMsg(user.getOpenId(), orderCode, buf.toString(), trade);
            msg.putWxMsg(wxmsg);

            // app 消息
            Map<String, String> appMsg = new HashMap<>();
            appMsg.put("orderId", changeOrder.getReturnCode());
            appMsg.put("userId", user.getId().toString());
            appMsg.put("orderType", "change");
        } else {
            logger.warn("换货单不存在：" + orderCode);
        }
    }

    @Override
    public void syncOrder(int timeInterval) {
        ygTaskTimeService.execute(TaskMethod.SyncWDTOrder, timeInterval, new YgTaskTimeTemplate() {

            @Override
            public void execute(Date runTime) throws Exception {
                Date startTime = DateConvertUtils.addMinute(runTime, -(timeInterval + 2));
                Date endTime = DateConvertUtils.addMinute(runTime, -2);
                logger.info("syncOrder 开始执行--> \r\nstartTime={} \r\n endTime={}", DateConvertUtils.formatDateTime(startTime),
                        DateConvertUtils.formatDateTime(endTime));
                List<YgOrderDetail> detailList = new ArrayList<>();
                List<YgReturnOrderDetail> rodList = new ArrayList<YgReturnOrderDetail>();

                TradeQueryResponse response = wdtQybTradeService.tradeQuery(startTime, endTime, null);
                List<TradesDTO> trades = response.getTrades();
                for (TradesDTO trade : trades) {
                    WdtQybOrder wdtQybOrder = new WdtQybOrder();
                    BeanUtils.copyProperties(trade, wdtQybOrder);
                    // 旺店通订单
                    if (isMOrder(trade.getShopNo())) {
                        // 合单时会有多个原始单号，（,分割）
                        String srcTidsStr = trade.getSrcTids();
                        String[] srcTids = srcTidsStr.split(",");
                        for (String tid : srcTids) {
                            String orderCode = WdtOrderBuiler.getOrderIdFromTid(tid);
                            boolean isNum = orderCode.matches("[0-9]+");
                            if (isNum) {
                                updateOrderStatus(orderCode, trade, detailList);
                            } else {
                                updateReturnStatus(orderCode, trade, detailList, rodList);
                            }
                        }
                    }
                }
                ygOrderDetailService.updateDetailSendBatch(detailList);
                ygReturnOrderDetailService.updateDetailStatusBatch(rodList);
                logger.info("syncOrder 执行结束");

            }

        });

    }

    private void updateReturnStatus(String orderCode, TradesDTO trade, List<YgOrderDetail> detailList, List<YgReturnOrderDetail> rodList) {
        YgReturnOrder ro = ygReturnOrderService.findDetailByReCode(orderCode);
        if (ro != null) {
            // 取消订单
            if (trade.getTradeStatus() == 5) {
                cancelReturnOrder(trade.getGoodsList(), ro, rodList);

            } else if (trade.getTradeStatus() == 55 || trade.getTradeStatus() == 95) {

                updateReturnDetailStatus(trade, ro, detailList, rodList);
            }
        }

    }

    private void updateReturnDetailStatus(TradesDTO trade, YgReturnOrder ro, List<YgOrderDetail> detailList, List<YgReturnOrderDetail> rodList) {

        // 55:审核通过 ;95:已发货
        OrderDetailStatus detailStatus = OrderDetailStatus.Audited;
        if (trade.getTradeStatus() == 95) {
            // 已发货
            detailStatus = OrderDetailStatus.WaitingSign;
        }

        for (TradeDetail goods : trade.getGoodsList()) {
            if (goods.getSrcOid().startsWith(ro.getReturnCode())) {
                for (YgReturnOrderDetail rod : ro.getReturnOrderDetails()) {
                    // 退换单自己的商品
                    if ((rod.getReturnCode() + "-" + rod.getId()).equals(goods.getSrcOid())) {
                        rod.setDetailStatus(detailStatus);
                        rodList.add(rod);
                    } else {
                        // 原单中的商品
                        String[] split = goods.getSrcOid().split("-");
                        Long orderDetailId = Long.parseLong(split[1]);
                        YgOrderDetail detail = ygOrderDetailService.findById(orderDetailId);
                        if (detail.getOrderId().equals(ro.getOrderId())) {
                            detail.setDetailStatus(detailStatus);
                            detailList.add(detail);
                        }
                    }
                }
            }
            // 旺店通子订单平台主键ID >> //
            // 订单编号+"-"+主键id

        }

    }

    private void cancelReturnOrder(List<TradeDetail> wdtDetails, YgReturnOrder ro, List<YgReturnOrderDetail> rodList) {
        List<YgReturnOrderDetail> rods = ro.getReturnOrderDetails();
        int cancelCount = 0;
        for (TradeDetail wd : wdtDetails) {
            for (YgReturnOrderDetail rod : rods) {
                if (wd.getSrcOid().equals(rod.getReturnCode() + "-" + rod.getId())) {
                    cancelCount++;
                }
            }

        }
        if (cancelCount == ro.getReturnOrderDetails().size()) {
            ygReturnOrderService.cancelReturn(ro.getReturnCode(), "您的" + ro.getReturnType().name() + "申请已取消。", "system");

        }

    }

    private void updateOrderStatus(String orderCode, TradesDTO trade, List<YgOrderDetail> detailList) {
        Long orderId = Long.parseLong(orderCode);
        YgOrder ygOrder = ygOrderService.findOrderDetailByOrderId(orderId);
        if (ygOrder != null) {
            // 取消订单
            if (trade.getTradeStatus() == 5) {
                cancelOrder(trade.getGoodsList(), ygOrder, detailList);

            } else if (trade.getTradeStatus() == 55 || trade.getTradeStatus() == 95) {
                updateDetailStatus(trade, ygOrder, detailList);
            }

            // 更新收货人信息
            updateReceiverInfo(trade, ygOrder);
        }

    }

    private void updateDetailStatus(TradesDTO trade, YgOrder ygOrder, List<YgOrderDetail> detailList) {

        // 55:审核通过 ;95:已发货
        OrderDetailStatus detailStatus = OrderDetailStatus.Audited;
        if (trade.getTradeStatus() == 95) {
            // 已发货
            detailStatus = OrderDetailStatus.WaitingSign;
        }
        for (YgOrderDetail detail : ygOrder.getOrderDetail()) {
            for (TradeDetail goods : trade.getGoodsList()) {
                // 旺店通子订单平台主键ID >> //
                // 订单编号+"-"+主键id
                if (goods.getSrcOid().equals(detail.getOutCode() + "-" + detail.getId())
                        || goods.getSrcOid().equals(detail.getOrderId() + "-" + detail.getId())) {
                    // if (goods.getRefundStatus() == 5) {
                    // detail.setRefundStatus(RefundStatus.RefundSuccess);
                    // }
                    detail.setRefundStatus(null);
                    detail.setDetailStatus(detailStatus);
                    detailList.add(detail);
                }
            }

        }

    }

    /**
     * @param @param trade
     * @param @param ygOrder 入参
     * @return void 返回类型
     * @throws @date 2017年6月20日 下午2:00:39
     * @Title: updateReceiverInfo
     * @Description: 更新收货人信息
     * @author （作者）
     * @version V1.0
     */
    private void updateReceiverInfo(TradesDTO trade, YgOrder ygOrder) {
        String sourceAddr = ygOrder.getReceiver() + " " + ygOrder.getTelPhone() + " " + ygOrder.getProvinceName() + " " + ygOrder.getCityName() + " "
                + ygOrder.getAreaName() + " " + ygOrder.getAddress();
        String newAddr = trade.getReceiverName() + " " + trade.getReceiverMobile() + " " + trade.getReceiverArea() + " " + trade.getReceiverAddress();
        if (!sourceAddr.equals(newAddr)) {
            String[] area = trade.getReceiverArea().split(" ");
            if (area.length == 3) {
                ygOrder.setProvinceName(area[0]);
                ygOrder.setCityName(area[1]);
                ygOrder.setAreaName(area[2]);
                ygOrder.setAddress(trade.getReceiverAddress());
                ygOrder.setReceiver(trade.getReceiverName());
                ygOrder.setTelPhone(trade.getReceiverMobile());
                ygOrderService.updateByOrderId(ygOrder);
            }
        }

    }

    private void cancelOrder(List<TradeDetail> wdtDetails, YgOrder ygOrder, List<YgOrderDetail> detailList) {

        List<YgOrderDetail> orderDetails = ygOrder.getOrderDetail();
        Long cancelCount = 0L;
        Long buyCount = orderDetails.stream().map(od -> od.getQuantity()).reduce(0L, (a, b) -> a + b);
        for (TradeDetail wdtDetail : wdtDetails) {
            for (YgOrderDetail detail : orderDetails) {
                if ((ygOrder.getOrderId() + "-" + detail.getId()).equals(wdtDetail.getSrcOid())) {
                    cancelCount += wdtDetail.getRefundNum().intValue();
                    if (wdtDetail.getRefundStatus() == 5) {
                        detail.setRefundStatus(RefundStatus.RefundSuccess);
                        detailList.add(detail);
                    }
                }
            }

        }
        if (cancelCount.equals(buyCount)) {
            ygOrder.setOrderStatus(OrderStatus.TradeClosed);
            ygOrder.setCancelTime(new Date());
            ygOrder.setCancelReason("系统同步旺店通订单。订单被取消。");
            ygOrderService.update(ygOrder);
            // 记录订单日志
            ygOrderLogService.addOrderLog(ygOrder.getOrderId(), OrderStatus.TradeClosed, "orderStatus4Send", "系统同步旺店通订单。订单被取消。");

            // 还优惠卷
            if (ygOrder.getCouponDetailId() != null) {

                YgCouponDetail ygCouponDetail = new YgCouponDetail();
                ygCouponDetail.setId(ygOrder.getCouponDetailId());
                ygCouponDetail.setUseStatus(CouponStatus.Received);
                ygCouponDetailService.update(ygCouponDetail);
            }

            // 还包邮卡
            ygCardCouponDetailService.returnExpressCard(ygOrder.getUserId(), ygOrder.getOrderId());
        }

    }

    @Override
    public void syncStockIn(int timeInterval) {
        ygTaskTimeService.execute(TaskMethod.SyncStockIn, timeInterval, new YgTaskTimeTemplate() {

            @Override
            public void execute(Date runTime) throws Exception {
                Date startTime = DateConvertUtils.addMinute(runTime, -(timeInterval + 2));
                Date endTime = DateConvertUtils.addMinute(runTime, -2);
                logger.info("syncStockIn 开始执行--> \r\nstartTime={}, endTime={}", DateConvertUtils.formatDateTime(startTime),
                        DateConvertUtils.formatDateTime(endTime));
                int pageNo = 0;
                int pageCount = 0;
                WdtQybResult result = null;
                List<WdtQybStockIn> stockInList = new ArrayList<WdtQybStockIn>();
                while (pageNo != -1) {
                    try {
                        result = wdtQybApi.queryStockIn(startTime, endTime, null, null, pageNo);
                    } catch (Exception e) {
                        logger.error("syncStockIn 执行失败--> \r\n {}" + ExceptionUtil.getExceptionMsg(e));
                        e.printStackTrace();
                        throw e;
                    }
                    List<WdtQybStockIn> list = result.getStockinList();

                    if (pageCount == 0) {
                        pageNo = pageCount = getPageCount(result.getTotalCount(), 30);
                        if (pageCount == 0) {
                            pageNo = -1;
                        }
                        continue;
                    }

                    stockInList.addAll(list);

                    pageNo--;

                }
                addStockIn(stockInList);
                logger.info("syncStockIn 执行结束--> \r\nstartTime={}, endTime={}", DateConvertUtils.formatDateTime(startTime),
                        DateConvertUtils.formatDateTime(endTime));
            }

            private void addStockIn(List<WdtQybStockIn> stockInList) {
                for (WdtQybStockIn in : stockInList) {
                    WdtQybStockIn qybStockIn = wdtQybStockInService.findByStockInId(in.getStockinId());
                    if (qybStockIn == null) {
                        int i = wdtQybStockInService.addStockIn(in);
                        if (i > 0 && in.getOrderType() == 1) {
                            adminPurchaseService.writeBackStorageStatus(in);
                        }
                    }

                }
            }
        });

    }

    @Override
    public void syncStockOut(int timeInterval) {
        ygTaskTimeService.execute(TaskMethod.SyncStockOut, timeInterval, new YgTaskTimeTemplate() {

            @Override
            public void execute(Date runTime) throws Exception {
                Date startTime = DateConvertUtils.addMinute(runTime, -(timeInterval + 2));
                Date endTime = DateConvertUtils.addMinute(runTime, -2);

                logger.info("syncStockOut 开始执行--> \r\nstartTime={}, endTime={}", DateConvertUtils.formatDateTime(startTime),
                        DateConvertUtils.formatDateTime(endTime));

                StockOutOrderQueryTradeResponse stockOutOrderQueryTradeResponse = wdtQybApi.querySaleStockOut(startTime, endTime, null, null, true);

                List<StockOutOrderTradeDTO> stockOutList = stockOutOrderQueryTradeResponse.getStockOutList();
                if (CollectionUtils.isEmpty(stockOutList)) {
                    return;
                }

                List<Integer> hasList = stockOutList.stream().map(StockOutOrderTradeDTO::getStockoutId).collect(Collectors.toList());
                // 删除重复
                wdtQybStockOutService.deleteBatch(hasList);

                wdtQybStockOutService.addBatchByDTO(stockOutList);

                // 保存批发商出库单明细
                ygWholesalerDeliveryOrderDetailService.addDeliveryOrderDetailAsyncByDTO(stockOutList);
                logger.info("syncStockOut 执行结束 --> \r\nstartTime={}, endTime={}", DateConvertUtils.formatDateTime(startTime),
                        DateConvertUtils.formatDateTime(endTime));
            }
        });
    }

    @Autowired
    private WdtQybStockService wdtQybStockService;

    @Override
    public void syncSkuStock() {
        Integer timeInterval = TaskMethod.SyncSkuStock.getCode();
        ygTaskTimeService.execute(TaskMethod.SyncSkuStock, timeInterval, new YgTaskTimeTemplate() {
            @Override
            public void execute(Date runTime) {
                Date startTime = DateConvertUtils.addMinute(runTime, -(timeInterval + 1));
                Date endTime = DateConvertUtils.addMinute(runTime, -1);
                Date currDate = new Date();

                logger.info("syncSkuStock 开始执行--> \r\nstartTime=【{}】, endTime=【{}】", DateConvertUtils.formatDateTime(startTime),
                        DateConvertUtils.formatDateTime(endTime));
                StockQueryResponse wdtResponse;
                try {
                    wdtResponse = wdtQybStockService.stockQuery(startTime, endTime, WdtStockSyncUtil.WAREHOUSE_NOS);
                } catch (Exception e) {
                    logger.error("syncSkuStock fail--> \r\n【{}】", e.getMessage(), e);
                    throw new RuntimeException(e);
                }
                List<YgStock> stockList = new ArrayList<>(wdtResponse.getTotalCount());
                if (CollectionUtils.isNotEmpty(wdtResponse.getStocks())) {
                    List<String> skuCodeList = wdtResponse.getStocks().stream().map(Stock::getSpecNo).distinct().
                            collect(Collectors.toList());
                    List<String> preList = ygProductService.findAllPreProductSkuCodes();
                    skuCodeList.forEach(skuCode -> {
                        YgStock stock = syncSkuStockBySkuCode(skuCode, preList, currDate);
                        if (stock != null) {
                            stockList.add(stock);
                        }
                    });
                }
                logger.info("syncSkuStock -->stockList: {}", stockList);
                ygStockService.updateBatchByTask(stockList);
                logger.info("syncSkuStock 执行结束--> \r\nstartTime={}, endTime={}", DateConvertUtils.formatDateTime(startTime),
                        DateConvertUtils.formatDateTime(endTime));
            }
        });


    }

    private YgStock syncSkuStockBySkuCode(String skuCode, List<String> preList, Date currDate) {
        StockQueryResponse wdtResponse;
        try {
            wdtResponse = wdtQybStockService.stockQuery(skuCode, WdtStockSyncUtil.WAREHOUSE_NOS);
        } catch (com.wdt.api.exception.WdtException e) {
            logger.error("syncSkuStockBySkuCode fail--> \r\n【{}】", e.getMessage(), e);
            throw new RuntimeException(e);
        }
        if (CollectionUtils.isEmpty(wdtResponse.getStocks())) {
            return null;
        }
        BigDecimal realAmount = BigDecimal.ZERO;
        BigDecimal amount = BigDecimal.ZERO;
        for (Stock stock : wdtResponse.getStocks()) {
            // real_amount（可发库存）=实际库存-预订单量-待审核量-未付款量-待发货量-锁定库存量
            realAmount = realAmount.add(WdtStockSyncUtil.getRealAmount(stock));
            //  计算后的 real_amount 大于1的情况下， real_amount *50% ，向上取整,更新 m 站的库存
            amount = amount.add(WdtStockSyncUtil.getAmount(realAmount));
        }
        if (CollectionUtils.isEmpty(preList)) {
            preList = ygProductService.findAllPreProductSkuCodes();
        }
        if (currDate == null) {
            currDate = new Date();
        }
        YgStock ygStock;
        if (preList.contains(skuCode)) {
            ygStock = new YgStock(skuCode, null, realAmount.longValue(), currDate, "sync");
        } else {
            ygStock = new YgStock(skuCode, amount.longValue(), realAmount.longValue(), currDate, "sync");
        }
        return ygStock;
    }

    /**
     * 基于旺店通库存同步方案
     */
    @Deprecated
    private void syncSkuStockOld() {
        Date currDate = new Date();
        WdtQybResult result = null;
        Boolean hasError = false;
        try {
            result = wdtQybApi.syncSkuStock(1000);
        } catch (Exception e) {
            hasError = true;
            logger.error("同步库存失败;" + e.getMessage());
            e.printStackTrace();
        }
        assert result != null;
        if (result.getCode() == 0) {
            List<YgStock> stockList = new ArrayList<YgStock>();
            List<WdtSkuStockBack> backList = new ArrayList<WdtSkuStockBack>();
            List<WdtQybStockChange> changeList = result.getStockChangeList();
            List<String> preList = ygProductService.findAllPreProductSkuCodes();
            for (int i = 0; i < changeList.size(); i++) {
                WdtQybStockChange stockChange = changeList.get(i);
                long amount = stockChange.getSyncStock();
                // Double realAmount = amount / 0.7;
                // 预售商品不同步M站库存
                YgStock stock = null;
                if (preList.contains(stockChange.getSpecId())) {
                    stock = new YgStock(stockChange.getSpecId(), null, amount, currDate, "sync");
                } else {
                    stock = new YgStock(stockChange.getSpecId(), amount, amount, currDate, "sync");
                }
                stockList.add(stock);
                // back
                WdtSkuStockBack back = new WdtSkuStockBack(stockChange.getRecId(), stockChange.getSyncStock(), stockChange.getStockChangeCount());
                backList.add(back);
            }
            if (stockList.size() > 0) {
                ygStockService.updateBatchByTask(stockList);
                try {
                    wdtQybApi.syncSkuStockBack(backList);
                } catch (WdtException e) {
                    logger.error("同步库存回调失败;" + e.getMessage());
                    hasError = true;
                    e.printStackTrace();
                }
            }
            if (!hasError) {
                ygTaskTimeService.saveOrUpdate(TaskMethod.SyncSkuStock.name(), currDate, "同步库存成功;");
            }
        }

    }

    private void loadLogistics(List<WdtSyncLogistics> trades) {
        threadPool.getExecutorService().execute(() -> {
            wdtQybLogisticsService.addBatch(trades);
            kidsOrderLogisticsService.loadKidsLogistics(trades);
        });

    }

    @Override
    public void loadLogistics() throws WdtException {
        Boolean doAgain = true;
        while (doAgain) {
            WdtSyncLogisticsResult result = wdtQybApi.syncLogistics(100, 1);
            if (result != null) {

                List<WdtSyncLogistics> trades = result.getTrades();
                wdtQybLogisticsService.addBatch(trades);
                if (trades.size() < 100) {
                    doAgain = false;
                }
            }

        }
    }

    private static Date PAY_TIME = DateUtils.parse("2016-01-01", DateUtils.DATE_FORMAT);

    @Override
    public void loadWdtOrder(int timeInterval) {
        ygTaskTimeService.execute(TaskMethod.LoadWDTOrder, timeInterval, new YgTaskTimeTemplate() {

            @Override
            public void execute(Date runTime) throws Exception {
                Date startTime = DateConvertUtils.addMinute(runTime, -(timeInterval + 2));
                Date endTime = DateConvertUtils.addMinute(runTime, -2);
                logger.info("loadWdtOrder 开始执行--> \r\nstartTime={}, endTime={}", DateConvertUtils.formatDateTime(startTime),
                        DateConvertUtils.formatDateTime(endTime));
                List<WdtQybOrder> tradeList = new ArrayList<>();
                List<Integer> srcRecIdList = new ArrayList<>();
                List<WdtQybOrderDetail> detailExistList = new ArrayList<>();
                List<WdtQybOrderDetail> detailNotExistList = new ArrayList<>();
                List<TradesDTO> tradesList = doQueryTrade(startTime, endTime);
                for (TradesDTO t : tradesList) {
                    if (t.getPayTime() != null && t.getPayTime().before(PAY_TIME)) {
                        continue;
                    }
                    Boolean exist = wdtQybOrderService.isExist(t.getTradeId());
                    if (StringUtil.isEmpty(t.getSrcTids())) {
                        t.setSrcTids(t.getTradeNo());
                    }
                    if (!exist) {
                        WdtQybOrder wdtQybOrder = new WdtQybOrder();
                        BeanUtils.copyProperties(t, wdtQybOrder);
                        tradeList.add(wdtQybOrder);
                    }
                    // ========================明细=====================
                    for (TradeDetail g : t.getGoodsList()) {
                        // m站订单
                        WdtQybOrderDetail detailClone = new WdtQybOrderDetail();
                        BeanUtils.copyProperties(g, detailClone);
                        detailClone.setShopNo(t.getShopNo());
                        detailClone.setShopName(t.getShopName());

                        Boolean detailExist = wdtQybOrderService.isDetailExist(g.getRecId());

                        if (detailExist) {
                            detailExistList.add(detailClone);
                        } else if (!srcRecIdList.contains(detailClone.getRecId())) {
                            srcRecIdList.add(detailClone.getRecId());
                            detailNotExistList.add(detailClone);
                        }
                    }
                }

                wdtQybOrderService.addBatch(tradeList);
                wdtQybOrderService.addDetailBatch(detailNotExistList);
                wdtQybOrderService.updateDetailBatch(detailExistList);
                logger.info("loadWdtOrder 执行结束--> \r\nstartTime={}, endTime={}", DateConvertUtils.formatDateTime(startTime),
                        DateConvertUtils.formatDateTime(endTime));
            }


        });
    }

    private List<TradesDTO> doQueryTrade(Date startTime, Date endTime) throws com.wdt.api.exception.WdtException {
//        TradeQueryResponse response = wdtQybTradeService.tradeQuery(startTime, endTime, null, null);
        TradeQueryResponse response = wdtQybTradeService.tradeQuery(startTime, endTime, null, null, true);
        List<TradesDTO> trades = response.getTrades();
//        trades.addAll(response1.getTrades());
        return trades;

    }

}
